"""

Roket Secure Language

"""

# Python Modules
import sys
import cPickle

# RSL Modules
import RSB
from ExpressionParser import *

class RSL():
	def __init__(self):
		self.engine = RSB.RSB();
		
		self.parser = ExpressionParser(self);
		
		self.filename = "<string>"
	
	def interpretCode(self, code):
		# This function interprets the code given to it, line-by-line, converting
		# RSL functions into bytecode where nessicary
		self.interpreter_indent_level = 0
		
		code = code.split("\n")
		bytecode = ""
		lineno = 1
		self.parser.current_file = self.filename
		
		for i in code:
			self.parser.current_line = lineno
			b = self.parser.parseExpression(i)
			if (not b.endswith("\n") and b.strip() != ""): b += "\n"
			bytecode += b
			lineno += 1
		b = self.parser.finalizeIndentations()
		if (not b.endswith("\n") and b.strip() != ""): b += "\n"
		bytecode += b
		
		# Write classes and functions to file
		f = open("main.rso", "wb")
		p = pickle.Pickler(f, pickle.HIGHEST_PROTOCOL)
		p.dump((self.engine.classes, self.engine.functions))
		f.close()
		
		f = open("main.rsb", "w")
		f.write(bytecode)
		f.close()
		
		self.engine.filename = "main.rsb"
		self.engine.runByteCode(bytecode.split("\n"))
	
	def interpretCodeProgressCallback(self, code, progress):
		# This function interprets the code given to it, line-by-line, converting
		# RSL functions into bytecode where nessicary
		self.interpreter_indent_level = 0
		
		code = code.split("\n")
		bytecode = ""
		lineno = 1
		self.parser.current_file = self.filename
		
		a = 0
		for i in code:
			self.parser.current_line = lineno
			progress(a, len(code))
			
			b = self.parser.parseExpression(i)
			if (not b.endswith("\n") and b.strip() != ""): b += "\n"
			bytecode += b
			a += 1
			lineno += 1
		b = self.parser.finalizeIndentations()
		if (not b.endswith("\n") and b.strip() != ""): b += "\n"
		bytecode += b
		
		return bytecode
		
	def runByteCode(self, bytecode, filename_main, filename_object):
		# Write base code to file
		f = open(filename_main, "w")
		f.write(bytecode)
		f.close()
		
		# Write classes and functions to file
		f = open(filename_object, "wb")
		p = cPickle.Pickler(f, cPickle.HIGHEST_PROTOCOL)
		p.dump((self.engine.classes, self.engine.functions))
		f.close()
		
		self.engine.filename = filename_main
		self.engine.runByteCode(bytecode.split("\n"))
		
	def runWithoutWriteByteCode(self, bytecode, filename_main):
		self.engine.filename = filename_main
		self.engine.runByteCode(bytecode.split("\n"))
		
	def loadByteCodeObject(self, filename_object):
		# Loads a .rso file's classes and functions into
		# the engine.  Can be used to load module code
		# to the engine on-the-fly (note that code in the
		# main area of the original .rsl file is not stored
		# in a .rso file, only functions and classes are).
		
		# Read classes and functions from file
		f = open(filename_object, "rb")
		p = cPickle.Unpickler(f)
		data = p.load()
		f.close()
		
		# Get the new functions/classes
		classes = data[0]
		functions = data[1]
		
		# Add them to the engine.
		self.engine.classes.update(classes)
		self.engine.functions.update(functions)